/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pro.unal.edu.filter;

import java.awt.Color;
import java.awt.Point;
import pro.unal.edu.datasource.BMPImage;
import pro.unal.edu.datasource.JPEGImage;
import pro.unal.edu.datasource.MyImage;
import pro.unal.edu.datasource.TIFFImage;

/**
 *
 * @author DavidN
 */
public class MyRotation {

    double beta = 0;     //Ángulo de rotación 

    public MyRotation(double beta) {
        this.beta = 2 * Math.PI - beta;
    }

    public Point doRotation(Point point) {
        float cos = (float) Math.cos(beta);
        float sin = (float) Math.sin(beta);
        double x = Math.round((point.getX() * cos) + (point.getY() * sin));
        double y = Math.round((point.getY() * cos) - (point.getX() * sin));
        Point p = new Point();
        p.setLocation(x, y);
        return p;
    }

    public Point doAntiRotation(Point point) {
        float cos = (float) Math.cos(beta);
        float sin = (float) Math.sin(beta);
        double x = Math.round((point.getX() * cos) - (point.getY() * sin));
        double y = Math.round((point.getX() * sin) + (point.getY() * cos));
        Point p = new Point();
        p.setLocation(x, y);
        return p;
    }

    public MyImage getImageRotated(MyImage myImage) {
        MyImage copy = null;
        if (myImage instanceof BMPImage) {
            copy = new BMPImage(myImage.getPathImage());
        } else if (myImage instanceof TIFFImage) {
            copy = new TIFFImage(myImage.getPathImage());
        } else if (myImage instanceof JPEGImage) {
            copy = new JPEGImage(myImage.getPathImage());
        }
        //copy.setDataImageColor(myImage.getDataImageColor());

        Point p00 = new Point(0, 0);
//        Point p01 = new Point(copy.getWidth() - 1, 0);
        Point p01 = new Point(copy.getWidth(), 0);
        Point p10 = new Point(0, copy.getHeight());
//        Point p10 = new Point(0, copy.getHeight() - 1);
//        Point p11 = new Point(copy.getWidth() - 1, copy.getHeight() - 1);
        Point p11 = new Point(copy.getWidth(), copy.getHeight());
        p00 = doRotation(p00);
        p01 = doRotation(p01);
        p10 = doRotation(p10);
        p11 = doRotation(p11);

        int minX1 = Math.min((int) p00.getX(), (int) p01.getX());
        int minX2 = Math.min((int) p10.getX(), (int) p11.getX());
        int minX3 = Math.min(minX1, minX2);

        int minY1 = Math.min((int) p00.getY(), (int) p01.getY());
        int minY2 = Math.min((int) p10.getY(), (int) p11.getY());
        int minY3 = Math.min(minY1, minY2);

        int maxX1 = Math.max((int) p00.getX(), (int) p01.getX());
        int maxX2 = Math.max((int) p10.getX(), (int) p11.getX());
        int maxX3 = Math.max(maxX1, maxX2);

        int maxY1 = Math.max((int) p00.getY(), (int) p01.getY());
        int maxY2 = Math.max((int) p10.getY(), (int) p11.getY());
        int maxY3 = Math.max(maxY1, maxY2);

        int heigh = maxY3 - minY3;
        int width = maxX3 - minX3;
//        Color[][] newImage = new Color[copy.getWidth()][copy.getHeight()];
        MyPoint[][] newImage = new MyPoint[width + 1][heigh + 1];
        int k = 0;
        cleanMatrix(newImage);
//            for (int j = copy.getHeight() - 1; j >= 0; j--) {
        for (int j = 0; j < copy.getHeight(); j++) {
            for (int i = 0; i < copy.getWidth(); i++) {
                Point myPoint = new Point(i, j);
                myPoint = doRotation(myPoint);
                Color c = copy.getDataImageColor()[i][j];
                int xP = Math.round((float) myPoint.getX() - minX3);
                int yP = Math.round((float) myPoint.getY() - minY3);
//                double xPd = myPoint.getX() - minX3;
//                double yPd = myPoint.getY() - minY3;
                Color c00 = new Color(0);
                Color c01 = new Color(0);
//                Color c02 = new Color(0);
//                Color c10 = new Color(0);
//                Color c11 = new Color(0);
//                Color c12 = new Color(0);
//                Color c20 = new Color(0);
//                Color c21 = new Color(0);
//                Color c22 = new Color(0);
                int xx = 0;
                int yy = 0;
                Point antiPoint = new Point();
                try {
//                    newImage[xP][yP].setColor(c);

                    antiPoint = new Point(xP + minX3, yP + minY3);
                    antiPoint = doAntiRotation(antiPoint);
                    xx = Math.round((float) (antiPoint.getX()));
                    yy = Math.round((float) (antiPoint.getY()));
                    c00 = copy.getDataImageColor()[xx][yy];

                    newImage[xP][yP].setColor(c00);
                } catch (Exception e) {
                }
                
                try {

                    antiPoint = new Point(xP + minX3 + 1, yP + minY3);
                    antiPoint = doAntiRotation(antiPoint);
                    xx = Math.round((float) (antiPoint.getX()));
                    yy = Math.round((float) (antiPoint.getY()));
                    c01 = copy.getDataImageColor()[xx][yy];

                    newImage[xP + 1][yP].setColor(c01);
                } catch (Exception e) {
                }
/*
                try {
                    antiPoint = new Point(xP + minX3, yP + minY3 + 1);
                    antiPoint = doAntiRotation(antiPoint);
                    xx = Math.round((float) (antiPoint.getX()));
                    yy = Math.round((float) (antiPoint.getY()));
                    c10 = copy.getDataImageColor()[xx][yy];
                    
                    newImage[xP][yP + 1].setColor(c10);
                } catch (Exception e) {
                }
                try {
                    antiPoint = new Point(xP + minX3 + 1, yP + minY3 + 1);
                    antiPoint = doAntiRotation(antiPoint);
                    xx = Math.round((float) (antiPoint.getX()));
                    yy = Math.round((float) (antiPoint.getY()));
                    c11 = copy.getDataImageColor()[xx][yy];
                    
                    newImage[xP + 1][yP + 1].setColor(c11);
                } catch (Exception e) {
                }
                
                */
                
//                try {
//                    antiPoint = new Point(xP + minX3 + 2, yP + minY3 + 2);
//                    antiPoint = doAntiRotation(antiPoint);
//                    xx = Math.round((float) (antiPoint.getX()));
//                    yy = Math.round((float) (antiPoint.getY()));
//                    c02 = copy.getDataImageColor()[xx][yy];
//                    
//                    newImage[xP + 2][yP].setColor(c02);
//                } catch (Exception e) {
//                }
//                try {
//                    antiPoint = new Point(xP + minX3 + 2, yP + minY3 + 1);
//                    antiPoint = doAntiRotation(antiPoint);
//                    xx = Math.round((float) (antiPoint.getX()));
//                    yy = Math.round((float) (antiPoint.getY()));
//                    c12 = copy.getDataImageColor()[xx][yy];
//                    
//                    newImage[xP + 2][yP + 1].setColor(c12);
//                } catch (Exception e) {
//                }
//                try {
//                    antiPoint = new Point(xP + minX3, yP + minY3 + 2);
//                    antiPoint = doAntiRotation(antiPoint);
//                    xx = Math.round((float) (antiPoint.getX()));
//                    yy = Math.round((float) (antiPoint.getY()));
//                    c20 = copy.getDataImageColor()[xx][yy];
//                    
//                    newImage[xP][yP + 2].setColor(c20);
//                } catch (Exception e) {
//                }
//                try {
//                    antiPoint = new Point(xP + minX3 + 1, yP + minY3 + 2);
//                    antiPoint = doAntiRotation(antiPoint);
//                    xx = Math.round((float) (antiPoint.getX()));
//                    yy = Math.round((float) (antiPoint.getY()));
//                    c21 = copy.getDataImageColor()[xx][yy];
//                    
//                    newImage[xP + 1][yP + 2].setColor(c21);
//                } catch (Exception e) {
//                }
//                try {
//                    antiPoint = new Point(xP + minX3 + 2, yP + minY3 + 2);
//                    antiPoint = doAntiRotation(antiPoint);
//                    xx = Math.round((float) (antiPoint.getX()));
//                    yy = Math.round((float) (antiPoint.getY()));
//                    c22 = copy.getDataImageColor()[xx][yy];
//                    
//                    newImage[xP + 2][yP + 2].setColor(c22);
//                } catch (Exception e) {
//                }
            }
            k++;
        }
        copy.setHeight(heigh);
        copy.setWidth(width);

        copy.setDataImageColor(newImage);
        return copy;
    }

    public void cleanMatrix(MyPoint[][] newImage) {
        for (int i = 0; i < newImage.length; i++) {
            for (int j = 0; j < newImage[0].length; j++) {
//                Color c = new Color(238, 238, 238);
                Color c = new Color(214, 217, 223);
                newImage[i][j] = new MyPoint(j, j, c);
            }
        }
    }
}